import * as React from 'react';
import { Installable } from '../../../common/protocol/installable';
import { ArduinoComponent } from '../../../common/protocol/arduino-component';
import { ComponentListItem } from './component-list-item';
import { ListItemRenderer } from './list-item-renderer';

export class ComponentList<T extends ArduinoComponent> extends React.Component<
    ComponentList.Props<T>
> {
    protected container?: HTMLElement;

    render(): React.ReactNode {
        return (
            <div className={'items-container'} ref={this.setRef}>
                {this.props.items.map((item) => this.createItem(item))}
            </div>
        );
    }

    componentDidMount(): void {
        if (this.container && this.props.resolveContainer) {
            this.props.resolveContainer(this.container);
        }
    }

    protected setRef = (element: HTMLElement | null) => {
        this.container = element || undefined;
    };

    protected createItem(item: T): React.ReactNode {
        return (
            <ComponentListItem<T>
                key={this.props.itemLabel(item)}
                item={item}
                itemRenderer={this.props.itemRenderer}
                install={this.props.install}
                uninstall={this.props.uninstall}
            />
        );
    }
}

export namespace ComponentList {
    export interface Props<T extends ArduinoComponent> {
        readonly items: T[];
        readonly itemLabel: (item: T) => string;
        readonly itemDeprecated: (item: T) => boolean;
        readonly itemRenderer: ListItemRenderer<T>;
        readonly install: (
            item: T,
            version?: Installable.Version
        ) => Promise<void>;
        readonly uninstall: (item: T) => Promise<void>;
        readonly resolveContainer: (element: HTMLElement) => void;
    }
}
